package com.camemax.netty.nio;

import java.io.File;

import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/**
 *  MappedByteBuffer支持三种IO模式：
 *  | -- "READ_ONLY" => 只读
 *  | -- "READ_WRITE" => 热修改
 *  | -- "PRIVATE" => ???
 */
public class NIOMappedByteBuffer {
    static String NIO_MAPPED_FILE = "D:\\javas\\netty\\files\\file03.txt";
    public static void main(String[] args) {
        File file = new File(NIO_MAPPED_FILE);
        FilePathCheck.checkDirectories(file);
        // channelReadOnly(file); // 只读
        channelReadWrite(file); // 热修改
    }
    // 只读Buffer
    private static void channelReadOnly(File file) {
        try {
            // RandomAccessFile既可以读写文件内容，支持直接跳转到文件的任意地方来读写数据。
            FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
            MappedByteBuffer readOnlyBuffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());
            readOnlyBuffer.put(0, (byte) 'R');
            readOnlyBuffer.put(1, (byte) 'E');
            readOnlyBuffer.put(2, (byte) 'A');
            readOnlyBuffer.put(3, (byte) 'D');
            readOnlyBuffer.put(4, (byte) 'O');
            readOnlyBuffer.put(5, (byte) 'N');
            readOnlyBuffer.put(6, (byte) 'L');
            readOnlyBuffer.put(7, (byte) 'Y');
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // 热修改Buffer
    private static void channelReadWrite(File file) {
        try {
            // RandomAccessFile既可以读写文件内容，支持直接跳转到文件的任意地方来读写数据。
            FileChannel channel = new RandomAccessFile(file, "rw").getChannel();

            System.out.println(file.getName() + " 文件长度 => " + channel.size()); // 空文件
            byte[] bytes = {'R', 'W'};
            /**
             * @MapMode:    通道读写模式
             * @position:   进行热修改的起始位置
             * @size:       内存映射大小，内存可以接收到的字节大小，即第0个位置开始，加载size个字节到内存中
             */
            MappedByteBuffer readWriteBuffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, 1); // java.nio.BufferOverflowException
            readWriteBuffer.put(bytes);
            System.out.println("热修改完成!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
